<!DOCTYPE html>
<html lang="en">

	<head>
		<meta charset="utf-8">
		<title>Hello world</title>
		<style>
			* {
				margin: 0;
				padding: 0;
			}

			.box {
				position: fixed;
				top: 50%;
				left: 50%;
				margin-top: -40vh;
				margin-left: -40vw;
				width: 80vw;
				height: 80vh;
			}

			.edit-wrapper {
				position: absolute;
				top: 0;
				left: 0;
				z-index: -10;
				opacity: 0;
				/*z-index: 10;
    opacity: 1;*/
				width: 100%;
				height: 100%;
				display: flex;
				justify-content: center;
				align-items: center;
				overflow: hidden;
			}

			.edit-wrapper.is-show {
				z-index: 10;
				opacity: 1;
			}

			.edit-content {
				position: absolute;
				z-index: 10;
				opacity: 1;
				left: 50%;
				top: 50%;
				transform: translate(-50%, -50%);
				transform-origin: center;
			}

			.edit-content .close-btn {
				position: absolute;
				z-index: 50;
				top: 40px;
				right: 40px;
				text-align: center;
				width: 32px;
				height: 32px;
				line-height: 30px;
				border: 1px solid #fff;
				border-radius: 50%;
				font-size: 24px;
				cursor: pointer;
				color: #fff;
				box-sizing: content-box;
			}

			.edit-content .xxb {
				position: absolute;
				z-index: 1;
				bottom: 10px;
				left: 0;
				right: 0;
				text-align: center;
				font-size: 30px;
				color: #409EFF;
			}

			.aa {
				width: 100%;
				height: 100%;
				opacity: 0.5;
			}

			.btn-box {
				position: fixed;
				top: 40px;
				left: 40px;
				z-index: 10;
			}
		</style>
	</head>

	<body>
		<div class="btn-box">
			<button onclick="showEditLineClick()">显示线</button>
			<button onclick="hideEdit()">隐藏</button>
		</div>
		<div class="box">
			<div class="aa"></div>
			<div class="edit-wrapper">
				<div class="edit-content">
					<div class="close-btn" onclick="oEdit.close()">×</div>
					<div style="width:100%; height:100%;" class="imageContainer"></div>
					<div class="xxb"></div>
				</div>
			</div>
		</div>
		<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
		<script src="./static/hammer.js"></script>
		<script src="./static/cornerstone.min.js"></script>
		<script src="./static/cornerstoneMath.min.js"></script>
		<script src="./static/cornerstoneWADOImageLoader.min.js"></script>
		<script src="./static/cornerstoneWebImageLoader.min.js"></script>
		<script src="./static/cornerstoneTools.min.js"></script>
		<script src="./static/dicomParser.min.js"></script>
		<script>
			const baseUrl = "http://127.0.0.1:8000/static/js/";
			const image_uir = '111'

			var config = {
				"胸膜增厚": "rgb(255, 0, 255)",
				"纤维灶": "rgb(220, 20, 60)",
				"钙化": "rgb(148, 0, 211)",
				"骨折": "rgb(123, 104, 238)",
				"肺不张": "rgb(0, 0, 205)",
				"肿块": "rgb(30, 144, 255)",
				"结节": "rgb(184, 134, 11)",
				"肺气肿": "rgb(0, 139, 0)",
				"气胸": "rgb(139, 35, 35)",
				"PICC": "rgb(218, 165, 32)",
				"积液": "rgb(255, 140, 0)",
				"积气": "rgb(0, 0, 0)",
				"实变": "rgb(85, 107, 47)",
				"术后金属": "rgb(95, 158, 160)",
				"膈下游离气体": "rgb(9,113,175)",
				"肠道积气扩张": "rgb(4,248,194)",
				"肠道积液液平": "rgb(148, 0, 211)",
				"泌尿系统结石": "rgb(108,227,33)"
			}



			var infos = {
				'111_ctr': {
					center_x: 1277,
					heart_x_begin_left: 936,
					heart_x_end_right: 2100,
					heart_y_begin_left: 1531,
					heart_y_end_right: 1621,
					lung_x_begin: 170,
					lung_x_end: 2348,
					lung_y: 1565,
					ratio: 0.5344,
				},
				'111_current': [{
					"name": "纤维灶",
					"confidence": 0.681,
					"xmin": 941,
					"ymin": 1033,
					"xmax": 1355,
					"ymax": 1318
				}, {
					"name": "结节",
					"confidence": 0.272,
					"xmin": 1175,
					"ymin": 812,
					"xmax": 1241,
					"ymax": 877
				}, {
					"name": "实变",
					"confidence": 0.079,
					"xmin": 947,
					"ymin": 1030,
					"xmax": 1349,
					"ymax": 1294
				}, {
					"name": "结节",
					"confidence": 0.036,
					"xmin": 977,
					"ymin": 1032,
					"xmax": 1124,
					"ymax": 1182
				}]
			}

			window.onload = function() {
				_initCornerstone();

				aaInitCornerstone();
			}

			function _initCornerstone() {
				cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
				cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
				cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
				cornerstoneTools.external.cornerstone = cornerstone;
				cornerstoneTools.external.Hammer = Hammer;

				// Image Loader
				const config = {
					webWorkerPath: `${baseUrl}assets/image-loader/cornerstoneWADOImageLoaderWebWorker.js`,
					taskConfiguration: {
						decodeTask: {
							codecsPath: `${baseUrl}assets/image-loader/cornerstoneWADOImageLoaderCodecs.js`,
						},
					},
				};
				cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
			}

			// 初始化影像
			function aaInitCornerstone() {
				let element = document.querySelector('.aa');
				cornerstone.enable(element);
				cornerstone.loadAndCacheImage(
					'wadouri:http://localhost:8088/static/data/1.2.840.1.19439.0.1000.20220101101114.1153.10000.3383340/1.2.840.113564.12312312360.2022010110184045329.1003000225002'
					).then(function(image) {
						oEdit.init(image);
					var viewport = cornerstone.getDefaultViewportForImage(element, image);
					cornerstone.displayImage(element, image, viewport);
				});
				element.addEventListener('cornerstoneimagerendered', onImageRendered);
			}

			function onImageRendered(e) {
				
			}

			// 显示编辑线
			function showEditLineClick() {
				oEdit.show({
					line: infos[image_uir + '_ctr'],
					rect: infos[image_uir + '_current']
				});
			}

			// 隐藏
			function hideEdit() {
				oEdit.close();
			}


			const oEdit = {
        visible: false,
        isInit: false,

        oWrapper: $('.edit-wrapper'),
        oContent: $('.edit-wrapper .edit-content'),
        oContainer: $('.edit-wrapper .imageContainer'),
        oCanvas: null,
        context: null,
        oXxb: $('.edit-wrapper .xxb'),
        // 图片数据
        image: {
          ratio: 0,
          width: 0,
          height: 0,
          file: null
        },
        // 编辑类型，line线，rect方框
        editType: '',
        // 数据
        oldData: null,
        newData: null,
        startData: null,
        // 路径
        paths: [],
        oPath: null,
        // 显示
        show(data) {
            this.oldData = JSON.parse(JSON.stringify(data));
            this.newData = JSON.parse(JSON.stringify(data));

            this.drawData();

            this.oWrapper.addClass('is-show');
            this.visible = true;

            // $('#myNavbar > .nav').hide();
            // $('#editRectBtn').text('保存');
        },
        // 关闭
        close() {
            // $('#myNavbar > .nav').show();
            // $('#editRectBtn').text('编辑');
            // this.oWrapper.removeClass('is-show');
            this.visible = false;
        },
        // 保存
        save() {
            infos[image_uir + "ctr"] = this.newData.line;
            infos[image_uir + "_current"] = this.newData.rect;
            drawReload($('#ctr_select').is(':checked'));
            setXxb(infos[image_uir + "ctr"].ratio);
            this.close();
        },
        // 初始化
        async init(image) {
            if(this.isInit) {
                return;
            }
            this.isInit = true;
            await this.initImageData(image);
            await waitTimeout(50);

            this.initEvent();
        },
        initEvent() {
          var context = this.context;
          var isDown = false;
          var downx = 0, downy = 0;

          this.oContainer.on('mousedown', 'canvas', (e) => {
            var canvas = this.oContainer[0].children[0];
            var rect = canvas.getBoundingClientRect();
            var x = e.clientX - rect.left;
            var y = e.clientY - rect.top;
            this.paths.forEach((item) => {
              if(context.isPointInPath(item.path, x/this.image.ratio, y/this.image.ratio)) {
                this.oPath = item;
                isDown = true;
                this.startData = JSON.parse(JSON.stringify(this.newData));
                downx = e.pageX;
                downy = e.pageY;
              }
            })
          })

          this.oContainer.on('mousemove', 'canvas', (e) => {
            // 如果当前是按下
            if(isDown) {
              var movex = e.pageX - downx;
              var movey = e.pageY - downy;
              if(this.oPath.type == 'line') {
                this.saveLineData(this.oPath.key, this.oPath.dir, movex/this.image.ratio, movey/this.image.ratio);
              } else if (this.oPath.type == 'rect') {
                this.saveRectData(this.oPath, movex/this.image.ratio, movey/this.image.ratio);
              }

            } else { // 非按下，移动改变canvas鼠标形状
              var canvas = this.oContainer[0].children[0];
              var rect = canvas.getBoundingClientRect();
              var x = e.clientX - rect.left;
              var y = e.clientY - rect.top;

              for(var i = 0; i < this.paths.length; i++) {
                var item = this.paths[i];
                if(context.isPointInPath(item.path, x/this.image.ratio, y/this.image.ratio)) {
                  canvas.style.cursor = item.cursor;
                  break;
                } else {
                  canvas.style.cursor = '';
                }
              }
            }
          })

          window.addEventListener('mouseup', function () {
            isDown = false;
          })
        },

        // 初始化图片宽高
        async initImageData(image) {
          // 设置宽高
          this.oContent.width(image.width);
          this.oContent.height(image.height);
          // 设置比例
          var ratio = 0;
          var boxw = this.oWrapper.width();
          var boxh = this.oWrapper.height();
          var min = Math.min(boxw, boxh);
          if (boxw / boxh >= image.width / image.height) {
            ratio = boxh / image.height;
          } else {
            ratio = boxw / image.width;
          }
          this.oContent.css({
            transform: `translate(-50%, -50%) scale(${ratio})`
          })
          this.image.ratio = ratio;

          // 设置图片
          cornerstone.enable(this.oContainer[0]);
          var viewport = cornerstone.getDefaultViewportForImage(this.oContainer[0], image);
          cornerstone.displayImage(this.oContainer[0], image, viewport);
          await waitTimeout(50);

          // 获取ctx对象
          this.oCanvas = this.oContainer[0].children[0];
          this.context = this.oCanvas.getContext('2d');
          // 保存图片
          var base64 = this.oCanvas.toDataURL('image/png');
          var img = new Image();
          img.src = base64;
          this.image.file = img;
        },

        // 保存线数据
        saveLineData(key, dir, movex, movey) {
            let oLine = this.newData.line;
            let startLine = this.startData.line;
            // 保存线位置数据
            oLine[key] = (dir == 'x' ? movex : movey) + startLine[key];
            // 计算心胸比
            oLine.ratio = (oLine.heart_x_end_right - oLine.heart_x_begin_left) / (oLine.lung_x_end - oLine.lung_x_begin);
            console.log(oLine);

            // 画数据
            this.drawData();
        },

        // 保存矩形数据
        saveRectData(path, movex, movey) {
            let oRect = this.newData.rect;
            let startRect = this.startData.rect;
            var index = path.index;
            if(path.dir == 'xy') {
                oRect[index].xmin = movex+startRect[index].xmin;
                oRect[index].xmax = movex+startRect[index].xmax;
                oRect[index].ymin = movey+startRect[index].ymin;
                oRect[index].ymax = movey+startRect[index].ymax;
            } else {
                oRect[index][path.key] = (path.dir == 'x' ? movex : movey)+startRect[index][path.key];
            }

            // 画数据
            this.drawData();
        },

        // 画数据
        drawData() {
            this.paths = [];
            // 清空画布
            this.oCanvas.width = this.oCanvas.width;
            // 绘制底图
            this.drawImage();
            // 画线，画框
            this.drawRect(this.newData.rect);
            this.drawLine(this.newData.line);
        },

        // 绘制底图
        drawImage() {
          this.context.drawImage(this.image.file,0,0);
        },

        // 画线
        drawLine(data) {
          var ctr = data;
          var context = this.context;
          var paths = [];

          var path = null;

          context.beginPath();
          context.lineWidth = 15;
          context.strokeStyle = "green"
          context.moveTo(ctr.lung_x_begin, ctr.lung_y);
          context.lineTo(ctr.lung_x_end, ctr.lung_y);
          context.closePath();
          context.stroke();

          // 绿色中线
          path = new Path2D();
          path.moveTo(ctr.lung_x_begin+20, ctr.lung_y-8);
          path.lineTo(ctr.lung_x_end-20, ctr.lung_y-8);
          path.lineTo(ctr.lung_x_end-20, ctr.lung_y+8);
          path.lineTo(ctr.lung_x_begin+20, ctr.lung_y+8);
          paths.push({
            type: 'line',
            cursor: 'n-resize',
            dir: 'y',
            path: path,
            key: 'lung_y'
          });
          // 绿色左
          path = new Path2D();
          path.moveTo(ctr.lung_x_begin, ctr.lung_y-8);
          path.lineTo(ctr.lung_x_begin+20, ctr.lung_y-8);
          path.lineTo(ctr.lung_x_begin+20, ctr.lung_y+8);
          path.lineTo(ctr.lung_x_begin, ctr.lung_y+8);
          paths.push({
            type: 'line',
            cursor: 'e-resize',
            dir: 'x',
            path: path,
            key: 'lung_x_begin'
          });
          // 绿色右
          path = new Path2D();
          path.moveTo(ctr.lung_x_end-20, ctr.lung_y-8);
          path.lineTo(ctr.lung_x_end, ctr.lung_y-8);
          path.lineTo(ctr.lung_x_end, ctr.lung_y+8);
          path.lineTo(ctr.lung_x_end-20, ctr.lung_y+8);
          paths.push({
            type: 'line',
            cursor: 'e-resize',
            dir: 'x',
            path: path,
            key: 'lung_x_end'
          });


          centerX = (ctr.lung_x_begin + ctr.lung_x_end) / 2
          Y = [ctr.lung_y, ctr.heart_y_begin_left, ctr.heart_y_end_right]
          minY = Math.min(...Y)
          maxY = Math.max(...Y)
          context.strokeStyle = "black"
          context.beginPath();
          context.moveTo(centerX, minY - 50);
          context.lineTo(centerX, maxY + 50);
          context.closePath();
          context.stroke();


          context.strokeStyle = "red"
          context.beginPath();
          context.moveTo(ctr.heart_x_begin_left, ctr.heart_y_begin_left);
          context.lineTo(centerX, ctr.heart_y_begin_left);
          context.closePath();
          context.stroke();

          // 红色线
          path = new Path2D();
          path.moveTo(ctr.heart_x_begin_left+20, ctr.heart_y_begin_left-8);
          path.lineTo(centerX, ctr.heart_y_begin_left-8);
          path.lineTo(centerX, ctr.heart_y_begin_left+8);
          path.lineTo(ctr.heart_x_begin_left+20, ctr.heart_y_begin_left+8);
          paths.push({
            type: 'line',
            cursor: 'n-resize',
            dir: 'y',
            path: path,
            key: 'heart_y_begin_left'
          });
          // 红色左
          path = new Path2D();
          path.moveTo(ctr.heart_x_begin_left, ctr.heart_y_begin_left-8);
          path.lineTo(ctr.heart_x_begin_left+20, ctr.heart_y_begin_left-8);
          path.lineTo(ctr.heart_x_begin_left+20, ctr.heart_y_begin_left+8);
          path.lineTo(ctr.heart_x_begin_left, ctr.heart_y_begin_left+8);
          paths.push({
            type: 'line',
            cursor: 'e-resize',
            dir: 'x',
            path: path,
            key: 'heart_x_begin_left'
          });

          context.beginPath();
          context.moveTo(centerX, ctr.heart_y_end_right);
          context.lineTo(ctr.heart_x_end_right, ctr.heart_y_end_right);
          context.closePath();
          context.stroke();
      
          // 红色线
          path = new Path2D();
          path.moveTo(centerX, ctr.heart_y_end_right-8);
          path.lineTo(ctr.heart_x_end_right-20, ctr.heart_y_end_right-8);
          path.lineTo(ctr.heart_x_end_right-20, ctr.heart_y_end_right+8);
          path.lineTo(centerX, ctr.heart_y_end_right+8);
          paths.push({
            type: 'line',
            cursor: 'n-resize',
            dir: 'y',
            path: path,
            key: 'heart_y_end_right'
          });
          // 红色右
          path = new Path2D();
          path.moveTo(ctr.heart_x_end_right-20, ctr.heart_y_end_right-8);
          path.lineTo(ctr.heart_x_end_right, ctr.heart_y_end_right-8);
          path.lineTo(ctr.heart_x_end_right, ctr.heart_y_end_right+8);
          path.lineTo(ctr.heart_x_end_right-20, ctr.heart_y_end_right+8);
          paths.push({
            type: 'line',
            cursor: 'e-resize',
            dir: 'x',
            path: path,
            key: 'heart_x_end_right'
          });

          this.paths.push(...paths.reverse());
        },

        // 画矩形
        drawRect(data) {
            var list = data;
            var context = this.context;
            var paths = [];

            var path = null;

            for(var i = 0; i < list.length; i++) {
                var item = list[i];
                var confidence = item.confidence;
                var label = item.name;
                var color = config[label];

                if (confidence !== 1) {
                    label = label + " " + confidence;
                }

                var xmin = item.xmin;
                var ymin = item.ymin;
                var xmax = item.xmax;
                var ymax = item.ymax;

                context.fillStyle = color;
                context.strokeStyle = color;
                context.lineWidth = 8;
                context.font = "60px 微软雅黑"
                context.beginPath();
                context.moveTo(xmin, ymin);
                context.lineTo(xmin, ymax);
                context.lineTo(xmax, ymax);
                context.lineTo(xmax, ymin);
                context.lineTo(xmin, ymin);
                context.fillText(label, xmin, ymin - 1)
                context.fillRect(xmin, ymin - 60, context.measureText(label).width, 60);
                context.closePath();
                context.stroke();
                context.fillStyle = "white"
                context.fillText(label, xmin, ymin - 1);

                // 添加path
                // 上
                path = new Path2D();
                path.moveTo(xmin+4, ymin-4);
                path.lineTo(xmax-4, ymin-4);
                path.lineTo(xmax-4, ymin+4);
                path.lineTo(xmin+4, ymin+4);
                paths.push({
                    type: 'rect',
                    cursor: 'n-resize',
                    dir: 'y',
                    path: path,
                    key: 'ymin',
                    index: i
                });
                // 右
                path = new Path2D();
                path.moveTo(xmax-4, ymin+4);
                path.lineTo(xmax-4, ymax-4);
                path.lineTo(xmax+4, ymax+4);
                path.lineTo(xmax+4, ymin-4);
                paths.push({
                    type: 'rect',
                    cursor: 'e-resize',
                    dir: 'x',
                    path: path,
                    key: 'xmax',
                    index: i
                });
                // 下
                path = new Path2D();
                path.moveTo(xmin+4, ymax-4);
                path.lineTo(xmax-4, ymax-4);
                path.lineTo(xmax-4, ymax+4);
                path.lineTo(xmin+4, ymax+4);
                paths.push({
                    type: 'rect',
                    cursor: 's-resize',
                    dir: 'y',
                    path: path,
                    key: 'ymax',
                    index: i
                });
                // 左
                path = new Path2D();
                path.moveTo(xmin-4, ymin+4);
                path.lineTo(xmin-4, ymax-4);
                path.lineTo(xmin+4, ymax-4);
                path.lineTo(xmin+4, ymin+4);
                paths.push({
                    type: 'rect',
                    cursor: 'w-resize',
                    dir: 'x',
                    path: path,
                    key: 'xmin',
                    index: i
                });
                // 中心
                path = new Path2D();
                path.moveTo(xmin+4, ymin+4);
                path.lineTo(xmin+4, ymax-4);
                path.lineTo(xmax-4, ymax-4);
                path.lineTo(xmax-4, ymin+4);
                path.lineTo(xmin+4, ymin+4);
                paths.push({
                    type: 'rect',
                    cursor: 'move',
                    dir: 'xy',
                    path: path,
                    index: i
                });
            }
            this.paths.push(...paths.reverse());
        },

        // 获取图片
        getImageFile(lineData, rectData) {
            this.drawLine(lineData, true);
            this.drawRect(rectData, false);
            // 保存图片
            var base64 = this.oCanvas.toDataURL('image/png');
            return base64ToFile(base64, '数据.png');
        }
      }


			const waitTimeout = function(time) {
				return new Promise((resolve, reject) => {
					setTimeout(() => {
						resolve();
					}, time);
				})
			}
		</script>
	</body>

</html>
